package driver

import (
	"github.com/gomodule/redigo/redis"
	"log"
	"sync"
	"time"
	"yunque-message-client/config"
)

/**
 * @Description
 * @Author yichen
 * @Date 2023/9/24 0024 10:52
 **/
type RedisDriver struct {
	name   string
	Closed bool
	Client *redis.Pool
	sync.Mutex
}

func NewRedisDriver() *RedisDriver {
	//v = New()
	return &RedisDriver{}
}
func (this *RedisDriver) SendTo(channelName string, data []byte) error {
	if channelName == "" {
		channelName = this.getChannelName()
	}
	err := this.SendPublish(channelName, data)
	//err := client.Send("Publish", "chat", data.Bytes())
	if err != nil {
		return err
	}
	return nil
}
func (this *RedisDriver) Get() *RedisDriver {
	return this.NewRedisClient()
}

// RedisClient2  init
func (this *RedisDriver) GetRedisPool() *RedisDriver {
	address := config.V().GetString("message.redis.conf.ip") + ":" + config.V().GetString("message.redis.conf.port")
	password := config.V().GetString("message.redis.conf.password")
	db := config.V().GetInt("message.redis.conf.db")
	MaxIdle := config.V().GetInt("message.redis.conf.maxIdle")
	Active := config.V().GetInt("message.redis.conf.active")
	Auth := config.V().GetBool("message.redis.conf.auth")
	IdleTimeout := config.V().GetInt("message.redis.conf.idleTimeout")
	this.Client = &redis.Pool{
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
		MaxIdle:     MaxIdle, //最初的连接数量
		MaxActive:   Active,  //最大连接数 0自动 按需分配
		IdleTimeout: time.Duration(IdleTimeout) * time.Second,
		Wait:        true, //超过连接数后是否等待
		Dial: func() (redis.Conn, error) {
			redisUri := address
			if Auth {
				redisCon, err := redis.Dial("tcp", redisUri,
					redis.DialPassword(password), redis.DialDatabase(db))
				if err != nil {
					log.Println("redisConn2 链接失败", err)
				}
				return redisCon, nil
			} else {
				redisCon, err := redis.Dial("tcp", redisUri, redis.DialDatabase(db))
				if err != nil {
					log.Println("redisConn3 链接失败", err)
				}
				return redisCon, nil
			}
		},
	}
	return this
}
func (this *RedisDriver) NewRedisClient() *RedisDriver {
	this.GetRedisPool()
	if this == nil || this.Closed || this.Client == nil {
		//1秒后重链
		time.Sleep(1 * time.Second)
		return this.NewRedisClient()
	}
	return this
}
func (rds *RedisDriver) Close() {
	rds.Closed = true
	defer func(Client *redis.Pool) {
		err := Client.Close()
		if err != nil {

		}
	}(rds.Client)
	return
}
func (rds *RedisDriver) SendPublish(channelName string, msg any) error {
	conn := rds.Get().Client.Get()
	defer rds.Close()
	err := conn.Send("Publish", channelName, msg)
	if err != nil {
		return err
	}
	err = conn.Flush()
	if err != nil {
		return err
	}
	return nil
}
func (this *RedisDriver) getChannelName() string {
	return config.V().GetString("message.redis.channelName")
}
